/*
 *IDistribution.cs
 * 
 * Copyright (c) 2003-2004, dnAnalytics. All rights reserved.
*/

using System;

namespace dnA.Stats.Distributions {
	///<summary>Base class for various distributions.</summary>
    public abstract class Distribution : IDistribution, IMoments {
		private readonly double mean;
		private readonly double variance;
		private readonly double skewness;
		private readonly double kurtosis;
		private readonly double std;

		internal static readonly double sqrt2pi = System.Math.Sqrt(System.Math.PI * 2);
		internal static readonly double sqrt2 = System.Math.Sqrt(2);
		
        ///<summary>Constructor sets the distribution's first four moments.</summary>
        ///<param name="mean">the distribution's mean.</param>
        ///<param name="variance">the distribution's mean.</param>
        ///<param name="skewness">the distribution's mean.</param>
        ///<param name="kurtosis">the distribution's mean.</param>
        ///<exception cref="ArgumentException">if the variance is negative.</exception>
        protected Distribution(double mean, double variance, double skewness, double kurtosis ){
			if( variance < 0 ) {
				throw new ArgumentException("variance must be positive.");
			}
			this.mean = mean;
			this.variance = variance;
			this.skewness = skewness;
			this.kurtosis = kurtosis;
			this.std = System.Math.Sqrt(this.variance);
		}

        ///<summary>The mean of the distribution.</summary>
		public double Mean{
			get{
				return mean;
			}
		}

        ///<summary>The variance of the distribution.</summary>
		public double Variance{
			get{
				return variance;
			}
		}

        ///<summary>The skewness of the distribution.</summary>
		public double Skewness{
			get{
				return skewness;
			}
		}

        ///<summary>The kurtosis of the distribution.</summary>
		public double  Kurtosis{
			get{
				return kurtosis;
			}
		}

        ///<summary>The standard deviation of the distribution.</summary>
		public double StandardDeviation{
			get{
				return std;
			}
		}

        ///<summary>Evaluates the probability density function at X.</summary>
        ///<param name="x">value to evaluate the function at.</param>
        ///<returns>the probability density function at X.</returns>
        public abstract double EvaluatePDF(double x);

        ///<summary>Evaluates the cumulative density function at X.</summary>
        ///<param name="x">value to evaluate the function at.</param>
        ///<returns>the cumulative density function function at X.</returns>
		public abstract double EvaluateCDF(double x);

        ///<summary>Evaluates the inverse cumulative density function at X.</summary>
        ///<param name="x">value to evaluate the function at.</param>
        ///<returns>the inverse cumulative density function function at X.</returns>
        public abstract double EvaluateInverseCDF(double x);
	}
}
